package com.di.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.di.base.dao.AccountTblDao;
import com.di.base.entity.AccountTbl;
import com.di.base.service.AccountTblService;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;

/**
 * (AccountTbl)表服务实现类
 *
 * @author makejava
 * @since 2025-07-08 22:45:19
 */
@Slf4j
@Service
public class AccountTblServiceImpl extends ServiceImpl<AccountTblDao, AccountTbl> implements AccountTblService {
    @Resource
    private AccountTblDao accountMapper;


    @Override
    @Transactional
    public boolean prepareDecreaseAccount(BusinessActionContext context,String userId, Double amount) {
        log.info("[TCC Try] 账户预扣余额，userId={}，amount={}", userId, amount);
        AccountTbl account = validateAccountAndBalance(userId, amount);
        account.setBalance(account.getBalance() - amount);
        account.setFrozen(account.getFrozen() + amount);
        accountMapper.updateById(account);
        return true;
    }

    @Override
    @Transactional
    public boolean commit(BusinessActionContext context) {
        String userId = context.getActionContext("userId").toString();
        Double amount = Double.valueOf(context.getActionContext("amount").toString());
        log.info("[TCC Confirm] 确认扣减冻结余额，userId={}，amount={}", userId, amount);

        AccountTbl account = accountMapper.selectOne(new QueryWrapper<AccountTbl>().lambda().eq(AccountTbl::getUserId, userId), false);
        account.setFrozen(account.getFrozen() - amount);
        accountMapper.updateById(account);
        return true;
    }

    @Override
    @Transactional
    public boolean rollback(BusinessActionContext context) {
        String userId = context.getActionContext("userId").toString();
        Double amount = Double.valueOf(context.getActionContext("amount").toString());
        log.info("[TCC Cancel] 回滚账户预扣余额，userId={}，amount={}", userId, amount);

        AccountTbl account = accountMapper.selectOne(new QueryWrapper<AccountTbl>().lambda().eq(AccountTbl::getUserId, userId), false);
        if (ObjectUtils.isEmpty(account)) {
            log.warn("取消阶段：账号{} 不存在，可能是Try阶段创建失败，无需回滚", userId);
            return true; // 不抛异常，表示已处理
        }
        account.setBalance(account.getBalance() + amount);
        account.setFrozen(account.getFrozen() - amount);
        accountMapper.updateById(account);
        return true;
    }

    /**
     * 校验账户是否存在以及余额是否充足
     *
     * @param userId 用户ID
     * @param amount 要扣减的金额
     * @return AccountTbl 实体
     */
    private AccountTbl validateAccountAndBalance(String userId, Double amount) {
        AccountTbl account = accountMapper.selectOne(new QueryWrapper<AccountTbl>().eq("user_id", userId), false);
        if (ObjectUtils.isEmpty(account)) {
            log.error("账号：{} 不存在", userId);
            throw new RuntimeException("账号：" + userId + " 不存在");
        }
        if (account.getBalance()< amount) {
            log.error("账户：{} 余额不足", userId);
            throw new RuntimeException("账户余额不足");
        }
        return account;
    }

}

